package com.kernowsoft.wavefx.specdraw;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class SpecData {

	private static final String TAG = "SpecData";

	public String sitename;
	public int numFreqs;
	public int numDirs;
	public float[] freqs = null;;
	public float[] dirs = null;;
	public float dth;
	public Float[][] spec2d = null;;
	public float lat, lon;
	public float windSpeed, windDir;
	public float[] freqBandWidth = null;;
	public float[] mn = null;
	

	public Date mDataTime, mValidTime;



	public SpecData() {
		sitename = "None";
	}

	public boolean decodeJsonString(String strJson) {

		// Parse the JSON string
		try {
			JSONObject json = new JSONObject(strJson);

			// Set scalar values:
			sitename = json.getString("sitename");
			lat = (float) json.getDouble("lat");
			lat = (float) json.getDouble("lon");
			windDir = (float) json.getDouble("wdir");
			windSpeed = (float) json.getDouble("wspd");

			numFreqs = json.getInt("nfreq");
			numDirs = json.getInt("ndir");
			
			// allocate and populate freqs and dirs arrays
			freqs = new float[numFreqs];
			dirs = new float[numDirs];
			
			// freqs[0] = json.getDouble("f0"); TODO: Add this to JSON at MO end!
			freqs[0] = 0.041f;	// TODO: Dont hardcode!
			for(int i = 1; i < numFreqs; i++) {
				freqs[i] = freqs[i-1] * 1.1f;
			}
			
			//float th0 = json.getDouble("th0"); TODO: Add this to JSON at MO end!
			float th0 = 0.0f;	// TODO: dont hardcode!
			dth = (float)Math.PI / numDirs;
			for(int j = 0; j < numDirs; j++) {
				dirs[j] = (float)Math.IEEEremainder(th0 + j * dth, 2*Math.PI); 
			}

			DateFormat df = new SimpleDateFormat("yyyy-mm-dd'T'HH:MM",
					Locale.ENGLISH);
			try {
				mValidTime = df.parse(json.getString("validtime"));
				mDataTime = df.parse(json.getString("datatime"));
			} catch (ParseException p) {
				Log.e(TAG, "Failed to parse date string: " + p.getMessage());
			}

			// allocate spectral data array:
			if (spec2d != null)
				spec2d = null; // so old data gets recycled (I think?)
			spec2d = new Float[numFreqs][numDirs];
		
			JSONArray data = new JSONArray(json.getString("specdata_flat"));
			for(int i = 0; i < numFreqs; i++) {
				for(int j = 0; j < numDirs; j++) {
					spec2d[i][j] = (float) data.getDouble(j + i * numDirs);		
				}
			}
			
		} catch (JSONException e) {
			e.printStackTrace();
		}

		return true;
	}
	
	public float[] integrate() {
		// integrate the 0th - 2nd moments of the spectra
		if(spec2d == null) {
			Log.w(TAG, "No 2D spectra loaded - can't integrate");
			return null;
		}
		
		if(mn != null) return mn;
		
		// allocate mn
		mn = new float[]{0.0f, 0.0f, 0.0f};
		
		
		// get spectral freq bandwidths:
		if(freqBandWidth == null)
			calcSpecBandwidths();

		// integrate over directions to 1D freq spectrum:
		float[] sume = new float[numFreqs];
		for(int ik = 0; ik < numFreqs; ik++) {
			sume[ik] = 0.0f;
			for(int ith = 0; ith < numDirs; ith++) {
				sume[ik] += spec2d[ik][ith];		
			}
			sume[ik] *= dth;
		} // at this point, we could store 1D spectrum for later plotting
		
		// integrate over freqs
		float e;
		for(int ik = 0; ik < numFreqs; ik++) {
			e = sume[ik] * freqBandWidth[ik];
			mn[0] += e;
			mn[1] += e * freqs[ik];
			mn[2] += e * Math.pow(freqs[ik], 2.0);
		}
		
		return mn;
	}

	public void calcSpecBandwidths() {
		if(freqs == null) return;
		freqBandWidth = new float[numFreqs];
		
		for(int ik = 0; ik < numFreqs; ik++) {
			freqBandWidth[ik] = 0.5f * (1.1f * freqs[ik] - freqs[ik] / 1.1f);
		}
	}
}
